# -*- coding:utf-8 -*-
import sys
import time

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget, QFileDialog, QApplication,QMessageBox
import os, threading
import subprocess
import shutil



class my_form(QWidget):
    def __init__(self):
        super().__init__()
        uic.loadUi('ui/pytoexeUI.ui', self)
        self.setWindowTitle("py_to_exe")
        # 初始化数据
        self.py_file_path = ''
        self.spec_file_name = ''
        self.old_file_path = os.getcwd()
        self.py_name = ''
        self.py_name_noext = ''
        #选择项目
        self.py_path_bt.clicked.connect(self.input_py_txt)
        # 选择图标
        self.ico_path_bt.clicked.connect(self.input_ico_txt)
        # 生成exe
        self.press_bt.clicked.connect(self.press_bt_)
        # 清除日志按钮
        self.qc_bt.clicked.connect(self.clear_bt_)
        self.op_exe_bt.clicked.connect(self.op_exe_bt_)


    def input_py_txt(self):
        fileName,fileType = QFileDialog.getOpenFileName(self, '选择需要打包的主程序', '', "Text Files(*.py)")
        py_file_path, py_file_name = os.path.split(fileName)
        fileNameNoExt, fileExt = os.path.splitext(py_file_name)
        self.py_path.setText(fileName)
        self.exe_name.setText(fileNameNoExt)
        self.py_name = py_file_name
        self.py_name_noext =fileNameNoExt

    def input_ico_txt(self):
        # os.getcwd()
        fileName, fileType = QFileDialog.getOpenFileName(self, '选择图标', '', "Text Files(*.ico)")
        self.ico_path.setText(fileName)

    #确定按钮
    def press_bt_(self):
        py_path_name = self.py_path.text()
        if py_path_name is None or py_path_name == '':
            QMessageBox.about(None, '提示', "请选择需要打包成exe的py文件")
            return False
        #生成spec文件
        self.build_spec_file()
        self.clear_build_dist()
        self.clear_bt_()
       # _thread.start_new_thread(self.bulid_cmd)
        t2 = threading.Thread(target=self.bulid_cmd)
        t2.start()

        #删除build 和dist 文件
    def clear_build_dist(self):
        build_dist = ['build', 'dist']
        for file_name in build_dist:
            file_dir = os.path.join(self.py_file_path, file_name)
            if os.path.isdir(file_dir):
                shutil.rmtree(file_dir)
    # 生成spec文件
    def build_spec_file(self):
        py_path_name = self.py_path.text()
        ico_path = self.ico_path.text()
        py_file_names = []
        py_file_path, py_file_name = os.path.split(py_path_name);
        fileNameNoExt, fileExt = os.path.splitext(py_file_name)
        datas = self.path_datas_(py_file_path)
        hiddenimports = self.hiddenimports_()
        exe_name = self.exe_name.text()
        console_type = self.cmd_show.isChecked()
        py_file_names.append(py_file_name)
        new_line = []
        old_spec_file = os.path.join(self.old_file_path, 'base.spec')
        with open(old_spec_file, 'r', encoding='utf-8') as file:
            for i in file:
                if 'py_name=None' in i:
                    new_line.append(str(py_file_names))
                    new_line.append(', \n')
                elif 'datas=None' in i:
                    text = 'datas=%s' % (datas)
                    new_line.append(text)
                    new_line.append(', \n')
                elif 'hiddenimports=None' in i:
                    text = 'hiddenimports=%s' % (hiddenimports)
                    new_line.append(text)
                    new_line.append(', \n')
                elif 'icon=None' in i:
                    if ico_path != '':
                        text = "icon='%s'" % (ico_path)
                        new_line.append(text)
                        new_line.append(', \n')
                elif 'name=None' in i:
                    text = "name='%s'" % (exe_name)
                    new_line.append(text)
                    new_line.append(', \n')
                elif 'console=None' in i:
                    text = 'console=' + str(console_type)
                    new_line.append(text)
                    new_line.append(', \n')
                else:
                    new_line.append(i)
        spec_file_name = fileNameNoExt + '.spec'
        new_spec_path = os.path.join(py_file_path, spec_file_name)
        outFile = open(new_spec_path, 'w', encoding='utf-8')
        for i in new_line:
            outFile.writelines(i)
        file.close()
        outFile.close()
        self.spec_file_name = spec_file_name
        self.py_file_path = py_file_path

    def bulid_cmd(self):
        os.chdir(self.py_file_path)
        rum_cmd = "pyinstaller %s" %(self.spec_file_name)
        p = subprocess.Popen(rum_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
        while True:
            out_data = p.stdout.readline()
            if not out_data and p.poll() is not None or p.poll() == '':
                break
            self.put_log_txt(out_data)
        print('ok')
        # 日志最后加空行
        for i in range(4):
            self.put_log_txt('')
        #将base.spec 拷贝到 编译文件内


    def put_log_txt(self, text):
        time.sleep(0.1)
        self.textEdit.append(text)


    # 将项目下面的文件进行复制
    def path_datas_(self, py_path):
        datas = []
        if py_path != '':
            specName = '%s%s' %(self.py_name_noext,'.spec')
            for root, dirs, files in os.walk(py_path):
                if '.' in root or '_' in root or 'build' in root or 'dist' in root:
                    continue
                for dir in dirs:
                    if '.' in dir or '_' in dir or 'build' == dir or 'dist' == dir:
                        continue
                    dir_path = os.path.join(root, dir)
                    dir_s = (dir_path, dir)
                    datas.append(dir_s)
            for files in os.listdir(py_path):
                if specName == files:
                    continue
                if files == self.py_name:
                    continue
                dir_path_file = os.path.join(py_path, files)
                if os.path.isfile(dir_path_file):
                    dir_s = (dir_path_file, '.')
                    datas.append(dir_s)
        return datas
    # 模块
    def hiddenimports_(self):
        model_txt = self.model.text()
        if model_txt != '':
            return str(model_txt).split(',')

    #清除日志
    def clear_bt_(self):
        self.textEdit.clear()

    # 打开文件夹
    def op_exe_bt_(self):
        ph = self.py_file_path
        if ph:
            dist_dir = os.path.join(self.py_file_path, 'dist')
            if os.path.isdir(dist_dir):
                os.startfile(dist_dir)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = my_form()
    main.show()
    sys.exit(app.exec_())